1. Technical Field of the Invention
The present invention generally relates to software debugging tools. More particularly, and not by way of any limitation, the present invention is directed to a system and method for setting and executing breakpoints and ranges of breakpoints.
2. Description of Related Art
In spite of the diversity among software program debuggers, they all share a common operational model. In order to fix a bug, the developer executes the program, and then uses a debugger to examine its behavior. Normally, he sets a breakpoint at an address location that is of some significance to the code, the machine on which it is being executed, or both, and the program is launched. When the breakpoint is reached during the runtime, control is returned to the user so that he can single-step forward, trying to delineate what happened in the execution. The user needs to activate the debugger, then run the debugged program and reproduce the problematic behavior.
Architecting testable software for high performance computing platforms has become a daunting task. In today's multiprocessor (MP) systems having a large number of processors in myriad architectural arrangements, the task is even more challenging. There exist numerous variations on the basic theme of multiprocessing. In general, these variations relate to how independently the processors operate and how the workload among these processors is distributed. In loosely-coupled multiprocessing architectures, the processors perform related tasks but they do so as if they were standalone processors. Each processor is typically provided with its own private memory and may have its own mass storage and input/output (I/O). Further, each loosely-coupled processor runs its own copy of an operating system (OS), and communicates with the other processor or processors through a message-passing scheme, much like devices communicating over a local area network.
In tightly-coupled multiprocessing architectures, on the other hand, operation of the processors is more closely integrated. They typically share main memory, and may even have a shared cache. The processors need not be identical to one another, and may or may not perform similar tasks. However, they typically share other system resources such as mass storage and I/O. Additionally, instead of a separate copy of the OS for each processor, they run a single copy, with the OS handling the coordination of tasks between the processors.
Hardware architectures for tightly-coupled MP platforms can be further divided into two broad categories. In symmetrical MP (SMP) systems, system resources such as memory, disk storage and I/O are shared by all the microprocessors in the system. The workload is distributed evenly to available processors so that one does not sit idle while another is heavily loaded with a specific task. Further, the SMP architecture is highly scalable, i.e., the performance of SMP systems increases, at least theoretically, as more processor units are added. In asymmetrical MP systems, tasks and resources are managed by different processor units. For example, one processor unit may handle I/O and another may handle network OS (NOS)-related tasks. Thus, it should be apparent that an asymmetrical MP system may not balance the workload.
As briefly alluded to hereinabove, designing software intended for reliable cross-platform execution on the numerous MP systems available nowadays has become an arduous undertaking. Further, with ever-shrinking design/debug cycle times, software developers are continuously looking for ways to streamline the debug operations necessary to architect well-tested code, be it application software, OS software, or firmware.
In addition, it should be appreciated that oftentimes the hardware development of a particular platform may not have advanced far enough to allow debug testing of the software code targeted for that platform. Typically, an architectural simulator is utilized in such instances. The simulator, which is operable to simulate a target hardware platform, can “execute” a particular piece of software intended for the target hardware as if it were run on the actual machine itself, and is provided with a debugger for debugging the software using the conventional breakpoint methodology as set forth in the foregoing.
The conventional process for setting and executing breakpoints for code debugging purposes, however, is beset with several limitations. First, although breakpoint ranges of limited form may be set in some circumstances, in general, a breakpoint must be set for every address where the user wishes the program to stop. In complex systems, this may equate to thousands or even millions of breakpoints. Second, a breakpoint cannot be set at a virtual address until a virtual-to-physical mapping has been established. Third, a breakpoint cannot be set at a physical address until the physical address has backing (i.e., an actual physical memory and the registers and routing circuitry necessary to get to the memory from the processor). Additionally, in order to determine during execution whether a breakpoint has been set at a particular address, the conventional breakpoint process requires that the content of the memory be retrieved from that address and delivered to the CPU before it can be determined whether a breakpoint is associated with the address. It can be appreciated that such a process is cumbersome, inefficient, and time-consuming.